package work.timejay.user.service.books.impl;
import java.time.LocalDateTime;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import sun.swing.StringUIClientPropertyKey;
import work.timejay.bo.CopyCategoryBO;
import work.timejay.common.ApiPageEntity;
import work.timejay.common.ApiResult;
import work.timejay.constants.CommonConstants;
import work.timejay.seleniums.ad2la.Ad2laUtils;
import work.timejay.service.CopyBooksCatalogueService;
import work.timejay.user.bo.BooksFindBO;
import work.timejay.user.dto.books.BookPageDTO;
import work.timejay.user.entity.books.BookType;
import work.timejay.user.entity.books.Books;
import work.timejay.user.entity.books.BooksCatalogue;
import work.timejay.user.mapper.books.BooksMapper;
import work.timejay.user.service.books.BookTypeService;
import work.timejay.user.service.books.BooksCatalogueService;
import work.timejay.user.service.books.BooksService;
import work.timejay.common.SuperServiceImpl;
import org.springframework.stereotype.Service;
import work.timejay.user.service.books.UserBooksService;
import work.timejay.user.vo.books.BookListVO;
import work.timejay.user.vo.books.BookPageVO;
import work.timejay.user.vo.books.BookTagsVO;
import work.timejay.utils.FileUtils;
import work.timejay.utils.MapUtils;

import java.util.*;

/**
 * <p>
 * 书本表 服务实现类
 * </p>
 *
 * @author 王文杰
 * @since 2023-11-28
 */
@Service
@Slf4j
public class BooksServiceImpl extends SuperServiceImpl<BooksMapper, Books> implements BooksService {

    @Autowired
    private FileUtils fileUtils;

    @Autowired
    private UserBooksService userBooksService;

    @Autowired
    private BookTypeService bookTypeService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private Ad2laUtils ad2laUtils;

    @Autowired
    private CopyBooksCatalogueService copyBooksCatalogueService;

    @Autowired
    private BooksCatalogueService booksCatalogueService;


    @Override
    public List<BookListVO> bookList(Integer type) {
        QueryWrapper<Books> qw = new QueryWrapper<>();
        if (type == 1) {
            qw.lambda()
                    .orderByDesc(Books::getGiveNum)
                    .last("LIMIT 10");
        } else {
            qw.lambda()
                    .orderByDesc(Books::getLikeNum)
                    .last("LIMIT 5");
        }
        List<Books> list = baseMapper.selectList(qw);
        List<BookListVO> voList = BeanUtil.copyToList(list, BookListVO.class);
        voList.forEach(e -> {
            if (StringUtils.isNotBlank(e.getBookPath())) {
                e.setBookPath(fileUtils.preview(e.getBookPath()));
            }
            if (StringUtils.isNotBlank(e.getCoverPath())) {
                e.setCoverPath(fileUtils.preview(e.getCoverPath()));
            }
        });
        return voList;
    }

    @Override
    public ApiPageEntity<BookPageVO> bookPage(BookPageDTO<Books> dto) {
        Page<Books> iPage = lambdaQuery()
                .orderByDesc(Books::getGiveNum)
                .page(dto.getPage());
        List<BookPageVO> voList = new ArrayList<>(iPage.getRecords().size());
        iPage.getRecords().forEach(e -> {
            BookPageVO bean = BeanUtil.toBean(e, BookPageVO.class);
            if (StringUtils.isNotBlank(e.getBookPath())) {
                bean.setBookPath(fileUtils.preview(e.getBookPath()));
            }
            if (StringUtils.isNotBlank(e.getCoverPath())) {
                bean.setCoverPath(fileUtils.preview(e.getCoverPath()));
            }
            BooksFindBO booksFindBO = userBooksService.findBookOneDayReadNumById(e.getId());
            BookType bookType = bookTypeService.findBookTypeByType(e.getType());
            if (null != bookType) {
                bean.setTypeName(bookType.getBookName());
            }
            bean.setReadNum(booksFindBO.getReadNum());
            bean.setPushNum(booksFindBO.getPushNum());
            bean.setGiveStatus(booksFindBO.getGiveStatus());
            bean.setOtherList(booksFindBO.getOtherList());
            voList.add(bean);
        });
        return ApiPageEntity.create(iPage, voList);
    }

    @Override
    public List<BookTagsVO> tags(Integer num) {
        List<BookTagsVO> voList = new ArrayList<>();
        Map<Object, Object> books = redisTemplate.opsForHash().entries("books");
        if (CollectionUtils.isNotEmpty(books)) {
            Map<String, String> resultMap = new HashMap<>();
            for (Map.Entry<Object, Object> item : books.entrySet()) {
                resultMap.put(item.getKey().toString(), item.getValue().toString());
            }
            resultMap = MapUtils.sortByValue(resultMap, true);
            int i = 0;
            for (Map.Entry<String, String> item : resultMap.entrySet()) {
                if (i == num) {
                    break;
                }
                i++;
                String[] split = item.getKey().split(CommonConstants.ACROSS);
                voList.add(new BookTagsVO(split[0], split[1]));
            }
        } else {
            List<Books> list = lambdaQuery()
                    .orderByDesc(Books::getGiveNum)
                    .last(CommonConstants.LIMIT + num)
                    .list();
            list.forEach(e -> {
                voList.add(new BookTagsVO(e.getId().toString(), e.getTitle()));
            });
        }
        return voList;
    }

    @Override
    public Books findBooksById(Long bookId,Boolean flag) {
        Books books = baseMapper.selectById(bookId);
        if(null == books){
            return books;
        }
        if (StringUtils.isNotBlank(books.getBookPath()) && flag) {
            books.setBookPath(fileUtils.preview(books.getBookPath()));
        }
        if (StringUtils.isNotBlank(books.getCoverPath())  && flag) {
            books.setCoverPath(fileUtils.preview(books.getCoverPath()));
        }
        return books;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchSave() {
        List<CopyCategoryBO> boList = ad2laUtils.analysisOfCategoriesData();
        List<Books> books = BeanUtil.copyToList(boList, Books.class);
        books.forEach(e->{
            e.setBookPath(e.getCoverPath());
            e.setId(IdWorker.getId());
        });
        log.info("books------->{}", JSONUtil.toJsonStr(books));
        saveBatch(books);
        copyBooksCatalogueService.updateHandlerStatusAll(true);
    }

    @Override
    public void batchSave(List<Books> books) {
        books.forEach(e->{
            e.setId(IdWorker.getId());
            save(e);
        });
        copyBooksCatalogueService.updateHandlerStatusAll(true);
    }

    @Override
    public List<Books> findBooksInfoList() {
        return lambdaQuery()
                .eq(Books::getHandlerStatus, 0)
                .list();
    }

    @Override
    public List<Books> findBooksTitle(String search) {
        List<Books> list = lambdaQuery()
                .like(Books::getTitle, search)
                .list();
        list.forEach(e->{
            if (StringUtils.isNotBlank(e.getBookPath())) {
                e.setBookPath(fileUtils.preview(e.getBookPath()));
            }
            if (StringUtils.isNotBlank(e.getCoverPath())) {
                e.setCoverPath(fileUtils.preview(e.getCoverPath()));
            }
        });
        return list;
    }
}
